<template>
	<view class="scroll-box">
		<scroll-view scroll-y class="scroll-list" 
			:refresher-enabled="isRefresh" @refresherrefresh="onRefreshData()" :refresher-triggered="refreshStatus" 
			@scroll="onscroll" :scroll-into-view="scrollInto" :scroll-with-animation="animation">
			<!-- 用于返回顶部 -->
			<view id="scroll-top"></view>
			
			<!-- 列表展示样式 -->
			<view v-show="list_status==1"><slot></slot></view>
			
			<!-- 底部加载更多 -->
			<view v-show="list_status==1" class="scroll-down">
				<u-loadmore :status="loadMore"/>
			</view>
		</scroll-view>
		
		<!-- 正在加载样式 -->
		<view v-if="list_status==2" class="position-box">
			<u-loading-icon vertical text="加载中..." size="30" textSize="16"></u-loading-icon>
		</view>
		
		<!-- 暂无数据样式 -->
		<view v-if="list_status==3" class="position-box" style="pointer-events: none">
			<u-empty text="暂无内容"></u-empty>
		</view>
		
		<!-- 返回顶部按钮 -->
		<u-back-top @click.self="onBackTop()" :scrollTop="scrollTop"></u-back-top>
	</view>
</template>

<script>
	let observer = null;
	export default {
		props: {
			// 是否开启下拉刷新
			isRefresh: {
				type: Boolean,
				default: false,
			},
			// 禁止首次自动请求
			noFirst: {
				type: Boolean,
				default: false,
			}
		},
		data() {
			return {
				list_status: 2,       // 1: 数据显示 2: 数据加载 3: 数据为空
				loadMore: 'loading',  // loading: 加载中, nomore: 加载完毕
				
				page: 1,
				
				refreshStatus: false, // 组件刷新状态
				animation: false,     // 开启滚动动画
				
				scrollTop: 0,         // 组件滚动的高度
				scrollInto: '',       // 定位到指定高度
			}
		},
		mounted() {
			// 获取节点实例
			observer = uni.createIntersectionObserver(this);
			// 监听节点显示和隐藏
			observer.relativeTo('.scroll-box').observe('.scroll-down', (res) => {
				if (res.intersectionRatio>0 && this.loadMore=='loading') {
					this.getListData(true);
				}
			});
			
			if(!this.noFirst) this.getListData();
		},
		beforeDestroy() {
			// 移除节点监听
			if(observer) observer.disconnect();
		},
		methods: {
			/* 重新加载数据 */
			onReloadData() {
				this.list_status = 2;
				this.scrollInto = 'scroll-top';
				setTimeout(() => { this.scrollInto='' }, 300);
				this.$nextTick(() => { 
					this.loadMore = 'loading';
					this.getListData();
				});
			},
			
			/* 组件下拉刷新 */
			onRefreshData() {
				this.refreshStatus = true;
				setTimeout(() => { 
					this.loadMore = 'loading';
					this.getListData();
				},800);
			},
			
			/* 获取列表数据 */
			getListData(bool) {
				this.page = bool ? (this.page+1) : 1;
				this.$emit('getListData', this.page, (nowNum, allNum) => {
					if(this.refreshStatus) this.refreshStatus = false // 关闭下拉刷新
					this.list_status = (allNum==0) ? 3 : 1; // 判断是否有数据
					this.loadMore = (nowNum==allNum) ? 'nomore' : 'loading' // 判断是否加载完毕
				});
			},
			
			/* 记录组件滚动高度 */
			onscroll({ detail }) { this.scrollTop=detail.scrollTop },
			
			/* 滚动到组件的顶部 */
			onBackTop() {
				this.animation = true;
				setTimeout(() => { this.scrollInto='scroll-top' }, 50);
				setTimeout(() => { 
					this.scrollInto='';
					this.animation = false;
				}, 300);
			},
		}
	}
</script>

<style scoped>
	.scroll-list {
		height: 100%;
		width: 100%;
	}
	.scroll-box {
		height: 100%;
		width: 100%;
		position: relative;
	}
	.position-box {
		position: absolute;
		top: 0; left: 0;
		width: 100%; height: 100%;
		overflow: hidden;
		display: grid;
		place-items: center;
	}
	.scroll-down {
		overflow: hidden;
	}
</style>